#-*- coding: utf-8 -*-

#--- PYTHON IMPORTS ---
from os import path

#--- FRAMEWORK IMPORTS ---
from django.contrib.auth.decorators import login_required
from django.contrib.auth.decorators import user_passes_test

from django.http import Http404
from django.http import HttpResponse
from django.http import HttpResponseRedirect
from django.http import HttpResponseForbidden

from django.shortcuts import get_object_or_404
from django.template import RequestContext
from django.utils.translation import ugettext as _
from django.shortcuts import render_to_response

#--- APP IMPORTS ---
from forms import *
from . import models
from . import control
from . import app_settings
from .snippet_773 import DiggPaginator

# main templates directory
templates_dir = "forum"

LISTABLE = {"forumgroup": lambda : models.ForumGroup.objects.all(), 
            "forum":lambda : models.Forum.objects.active(),
            "topic": models.Topic.objects.active()}

def rp(template_path, context_dict, request):
    "A wrapper for render_to_response"
    return render_to_response(path.join(templates_dir, template_path), context_dict, 
                              context_instance=RequestContext(request))

#--- VIEWS ---

def expose_index(request, template_name="index.html"):
    """Retorna uma lista com os grupos de forum"""
    return rp(template_name, {'fg_list':control.fg_list()}, request)

@login_required
def expose_post(request, pk, slug, template_name="edit.html"):
    'Cria um novo topico para um forum'
    forum = control.get_forum(pk)
    
    if request.method == "POST":
        form = TopicForm(request.POST, request.FILES)
        
        if form.is_valid():
            reply_form = ReplyForm(request.POST)
            
            if reply_form.is_valid():
                tp_ins = form.save(commit=False)
                tp_ins.author = request.user
                tp_ins.forum = forum
                tp_ins.save()
                
                rp_ins = reply_form.save(commit=False)
                rp_ins.author = request.user
                rp_ins.topic = tp_ins
                rp_ins.save()
                return HttpResponseRedirect( tp_ins.link() )
    else: form = TopicForm()
    
    return rp(template_name, {'forum':forum, 'form':form}, request)

def expose_forum(request, pk, slug, template_name="forum.html"):
    'Mostra um forum'
    forum = control.get_forum(pk)

    if control.frm_require_login(request, forum): 
        return HttpResponseRedirect(control.login_redirect(request.path))

    query = control.tp_list(request.user, forum)
    page_number = request.GET.get('page', 1)
    paginator = DiggPaginator(query, app_settings.SMALL_LIST, **app_settings.DIGG)
    page = paginator.page(page_number)
    
    return rp('forum.html', {'forum':forum, 'page':page}, request)

def expose_topic(request, pk, slug, template_name="topic.html"):
    'Mostra um topico'
    topic, forum = control.get_topic(pk, request.user)
    
    if control.frm_require_login(request, forum): 
        return HttpResponseRedirect(control.login_redirect(request.path))
    
    IS_FOLLOWING = control.is_following(request.user, topic)
    IS_MODERATOR = control.is_moderator(request.user, forum)
    
    query = topic.reply_list.active()    
    page_number = request.GET.get('page', 1)
    paginator = DiggPaginator(query, app_settings.SMALL_LIST, **app_settings.DIGG)
    page = paginator.page(page_number)
    topic.update_views(request)
    
    return rp(template_name, {
        'forum':forum, 'topic':topic,
        'IS_FOLLOWING':IS_FOLLOWING, 'IS_MODERATOR':IS_MODERATOR,
        'page':page}, request)

@login_required
def expose_moderate(request, pk, slug, template_name="edit.html"):
    topic, forum = control.get_topic(pk, request.user)
    next = request.GET.get('next', None)
    
    if control.is_moderator(request.user, forum):
        form_title=_("Moderating topic '%s'") % topic.title
        if request.method=='POST':
            form = ModerateForm(request.POST, instance=topic)
            if form.is_valid():
                ins = form.save()

                if next:
                    return HttpResponseRedirect( next )
                else: return HttpResponseRedirect( ins.link() )
        else:
            form = ModerateForm(instance=topic)
        return rp(template_name, {"form":form, "form_title":form_title}, request)
    else: HttpResponseForbidden(_("You don't have permission to do that."))

@login_required
def expose_follow(request, pk, slug, active):
    topic, forum = control.get_topic(pk, request.user)
    control.follow(request.user.frm_profile, topic, active)
    return HttpResponseRedirect(topic.link())

@login_required
def expose_del_topic(request, pk):
    topic, forum = control.get_topic(tp_pk, request.user)
    
    # só quem pode remover um topico é o moderador
    if control.can_del(request.user, topic, forum):
        topic.active=False
        topic.save()
        return HttpResponseRedirect(forum.link())
    else: return HttpResponseForbidden(_("You don't have permission for this action."))

@login_required
def expose_edit_reply(request, pk, template_name="edit.html"):
    reply = control.get_reply(pk)
    topic = reply.topic
    forum = topic.forum
    
    if control.can_edit(request.user, reply, forum):
        if request.method=="POST":
            form = ReplyForm(request.POST, instance=reply)
            if form.is_valid():
                reply = form.save()
                request.user.message_set.create(message=ugettext('Reply edited.'))
                return HttpResponseRedirect(reply.link())
        else:
            form_title = _("Editing '%s'") % reply.title or _('reply')
            form = ReplyForm(instance=reply)
        
        return rp('edit.html', 
            {'forum':forum, 'topic':topic, 'reply':reply, 'form':form, 'form_title':form_title}, request)
        
    else: return HttpResponseForbidden(_('only the author can do that.'))

@login_required
def expose_reply(request, pk, slug, template_name="edit.html"):
    'Permite responder um topico'
    topic, forum = control.get_topic(pk, request.user)
    
    if request.method=="POST":
        form = ReplyForm(request.POST)
        if form.is_valid():
            
            instance = form.save(commit=False)
            instance.author = request.user
            instance.topic = topic
            instance.forum = forum
            instance.save()
            return HttpResponseRedirect( topic.link() )
    else: form = ReplyForm()
    return rp(template_name, {'topic':topic, 'forum':forum, 'form':form}, request)

@login_required
def expose_del_reply(request, pk):
    'Permite desativar um tópic'
    reply = control.get_reply(pk)
    topic = reply.topic
    forum = topic.forum
    
    if reply.author == request.user:
        reply.active=False
        reply.save()
        request.user.message_set.create(message=ugettext('Reply erased.'))
        return HttpResponseRedirect(topic.link())
    else: return HttpResponseForbidden(_('only the author can do that.'))

def user_profile(request, username, template_name="user/default.html"):
    """Shows the public forum profile from an user
    Arguments:
    username - name of the user you want to see
    """
    frm_user = control.get_user(username=username)
    frm_profile = frm_user.frm_profile
    return rp(template_name, 
        {'frm_user':frm_user, 'frm_profile':frm_profile}, request)

@login_required
def expose_edit_profile(request, template_name='edit.html'):
    frm_user = request.user
    frm_profile = frm_user.frm_profile
    
    if request.method=="POST":
        form = UserProfileForm(request.POST, request.FILES, instance=frm_profile)
        if form.is_valid():
            form.save()            
            frm_user.message_set.get_or_create(message=_('Profile updated.'))
            return HttpResponseRedirect( frm_profile.link() )
    else:
        form = UserProfileForm(instance=frm_profile)
    return rp(template_name, {'frm_profile':frm_profile, 'form':form}, request)

@login_required
def send_pvt(request, username, template_name="user/send_pvt.html"):
    """Used to send a private message to an user
    Arguments:
    username - name of the user you want to message"""
    frm_user = control.get_user(username=username)
    frm_profile = frm_user.frm_profile
    
    if request.method=="POST":
        form = SendPvtForm(request.POST)

        if form.is_valid():
            instance, status = form.save(request.user, frm_profile.message_box)
            
            if status=='ok':
                request.user.message_set.create(message=_("Message sent."))
            elif status=='full':
                request.user.message_set.create(message=_("Message can't be sent because user's message box is full."))
            return HttpResponseRedirect( frm_profile.link().send_pvt() )
    else:
        form = SendPvtForm()
    return rp(template_name,
        {"frm_user":frm_user, "frm_profile":frm_profile, "form":form}, request)

@login_required
def del_pvt_msg(request, message_id):
    frm_user = request.user 
    frm_profile = frm_user.frm_profile
    msg_box = frm_profile.message_box
    frm_message = control.get_msg(msg_box, message_id)    
    frm_message.delete()
    request.user.message_set.create(message=_("'%s' removed." % frm_message))
    return HttpResponseRedirect(frm_profile.link().msg_box())

@login_required
def message_box(request, message_id=None, template_name="user/message_box.html"):
    frm_user, frm_profile = request.user, request.user.frm_profile
    msg_box = frm_profile.message_box
    frm_message = None
    
    if message_id is not None:
        frm_message = control.get_msg(msg_box, message_id)
        return rp("user/frm_message.html", 
                  {"frm_user":frm_user, "frm_profile":frm_profile, 
                   "msg_box":msg_box, "frm_message":frm_message}, request)
    
    page_number = request.GET.get('page', 1)
    query = msg_box.messages.all()
    paginator = DiggPaginator(query, app_settings.SMALL_LIST, **app_settings.DIGG)
    page = paginator.page(page_number)
    
    return rp(template_name, 
        {"frm_user":frm_user, "frm_profile":frm_profile, 
        "msg_box":msg_box, "frm_message":frm_message, "page":page}, request)

def expose_gallery(request, username, name=None, item_id=None, template_name="user/gallery.html"):
    'mostra a galeria do usuário'
    frm_user = control.get_user(username=username)
    frm_profile = frm_user.frm_profile
    
    galleries=ImageGallery.objects.filter(owner=forum_profile)
    gallery, item=None, None
    
    if name is not None:
        gallery = galleries.get(label=name)
    if item is not None:
        item=gallery.get(PK=item_id)
    
    return rp(template_name, 
        {"forum_user":forum_user, "forum_profile":forum_profile,
        "galleries":galleries, "gallery":gallery, "item":item}, request)

@login_required
def expose_friends(request, template_name="user/friends.html"):
    'Mostra a lista de amigos do usuario'
    frm_user, frm_profile = request.user, request.user.frm_profile
    
    page_number = request.GET.get('page', 1)    
    query = frm_profile.friends.all()
    paginator = DiggPaginator(query, app_settings.SMALL_LIST, **app_settings.DIGG)
    page = paginator.page(page_number)
    
    return rp(template_name, 
            {"frm_user":frm_user, "frm_profile":frm_profile, 
             "page":page}, request)

@login_required
def expose_add_friend(request, username):
    friend = control.get_user(username=username)
    friend_profile = friend.frm_profile
    
    user_frm_profile = request.user.frm_profile
    user_frm_profile.add_friend(friend_profile)
    
    request.user.message_set.create(message=_("%s is now your new friend.") % friend)    
    return HttpResponseRedirect( friend_profile.link() )

@login_required
def expose_remove_friend(request, username):
    friend = control.get_user(username=username)
    friend_profile = friend.frm_profile
    
    user_frm_profile = request.user.frm_profile
    user_frm_profile.remove_friend(friend_profile)
    
    request.user.message_set.create(message=_("%s is your friend no longer.") % friend)
    return HttpResponseRedirect( user_frm_profile.link().friends() )

@login_required
def report_abuse(request, pk, slug, template_name="edit.html"):
    topic, forum = control.get_topic(pk, request.user)
    form_title = _('Abuse report for "%(tp)s" from "%(author)s"') % {"tp":topic, "author":topic.author}
    
    if request.POST:
        form = ReportAbuseForm(request.POST)
        if form.is_valid():
            ins_rep = form.save(commit=False)
            ins_rep.topic=topic
            ins_rep.author=request.user
            ins_rep.save()
            request.user.message_set.create(message=_('Your complaint will be investigated.'))
            return HttpResponseRedirect(topic.link())
    else:
        form = ReportAbuseForm()
    return rp(template_name, {'topic':topic, 'form':form, 'form_title':form_title}, request)

def search(request, template_name="search.html"):
    page_number=request.GET.get('page', 1)
    
    if request.method == "POST":
        form=SearchForm(request.POST)
        if form.is_valid():
            query = form.query            
            paginator = DiggPaginator(query, app_settings.BIG_LIST, **app_settings.DIGG)
            page = paginator.page(page_number)
            return rp(template_name, {'page':page, 'form':form}, request)
    
    elif request.GET:
        form=SearchForm(request.GET)
        if form.is_valid():
            query = form.query
            paginator = DiggPaginator(query, app_settings.BIG_LIST, **app_settings.DIGG)
            page = paginator.page(page_number)
            return rp(template_name, {'page':page, 'form':form}, request)
    else:
        form=SearchForm()
        return rp(template_name, {'form':form}, request)
